#include "undomanager.h"
#include "action.h"

bool UndoManager::undo()
{
	bool undid = false;
	while(getCurrentIndex() >= 0 && !undid)
	{
		undid |= m_stack.get(getCurrentIndex())->undo();
		m_index--;
	}
	return undid;
}

bool UndoManager::redo()
{
	bool did = false;
	while(getCurrentIndex() < m_stack.size()-1 && !did)
	{
		did |= m_stack.get(getCurrentIndex()+1)->redo();
		m_index++;
	}
	return did;
}

/**
 * @param a_action the action to add to the undo manager. it may modify itself when execute() is called
 * @param a_doAction whether or not to execute the action after adding it to the undo stack
 */
void UndoManager::addAction(Action & a_action, const bool & a_doAction)
{
	Action * a = getCurrentAction();
	if(a && a->isCombinable(a_action))
	{
		a->combine(a_action);
	}
	else	// if the action can't be combined, it will need new memory
	{
		Action * action = a_action.clone();
		m_stack.setSize(m_index+1);
		m_stack.set(m_index, action);
		m_index++;
	}
	if(a_doAction)
	{
		a_action.execute();
	}
}

void UndoManager::addAction(Action & a_action)
{
	addAction(a_action, false);
}

void UndoManager::release()
{
	for(int i = 0; i < m_stack.size(); ++i)
	{
		delete m_stack.get(i);
	}
	m_stack.release();
}
